//@author A0121492M
import java.text.SimpleDateFormat;

public class EditCommand extends Command {
	public boolean isEditingTitle = false;
    public boolean isEditingPlace = false;
    public boolean isEditingStartTime = false;
    public boolean isEditingEndTime = false;
    public boolean isEditingProject = false;
    public boolean isEditingDescription = false;
    public Task newTaskDetails = null;
    public int taskId = Task.EMPTY_ID;
    public String taskTitle = Task.EMPTY_STRING;
	public boolean isGuiOpenCommand = false;
    private Task editFrom = new Task();
    private Task editTo = new Task();
    private String datesError = "Error: start time (%1$s) comes after end time (%2$s)";
    private String defaultTimeFormat = "dd/MM/yyyy HH:mm";

	public ExecutionReply execute() throws TaskNotFoundException, 
			PopupClosedException, NotUniqueException, InvalidInputException {
		assert(this.taskId != Task.EMPTY_ID ^ this.taskTitle != Task.EMPTY_STRING);
		int index = getTaskIndex();
		fillEditFromAndEditTo(index);
		
		Logic.loadedData.set(index, editTo);
		Logic.saveData();
		Logic.updateCommandHistory(this);
		
		SingleTaskReply s = new SingleTaskReply();
		s.task = editTo;
		return s;
	}
	
	private void fillEditFromAndEditTo(int index) throws 
			PopupClosedException, TaskNotFoundException, InvalidInputException {
		if (index == -1) {
			throw new TaskNotFoundException();
		} else if (this.isGuiOpenCommand == false) {
			editFrom = Logic.loadedData.get(index);
			editTo = mergeTasks(editFrom.clone());
		} else if (this.isGuiOpenCommand == true) {
			editFrom = Logic.loadedData.get(index);
			editTo = PopUps.executeEdit(editFrom);
			Logic.checkIfPopupClosed(editTo);
		}
		
		if (datesAreReversed()) {
			throwReversedDateError(editTo);
		}
	}

	private int getTaskIndex() throws TaskNotFoundException, NotUniqueException {
		if (this.taskId != Task.EMPTY_ID) {
			Task dummy = new Task();
			dummy.id = this.taskId;
			return Logic.loadedData.indexOf(dummy);
		} else if (this.taskTitle != Task.EMPTY_STRING) {
			return Logic.findIndexByTitle(this.taskTitle);
		}
		return -1;
	}

	private void throwReversedDateError(Task task) throws InvalidInputException {
		SimpleDateFormat sdf = new SimpleDateFormat(defaultTimeFormat);
		throw new InvalidInputException(String.format(
				datesError,
				sdf.format(task.startTime), sdf.format(task.endTime)));
	}

	public void undo() {
		int index = Logic.loadedData.indexOf(editFrom);
		Logic.loadedData.set(index, editFrom);
	}
	
	public void redo() {
		int index = Logic.loadedData.indexOf(editTo);
		Logic.loadedData.set(index, editTo);
	}
	
	private Task mergeTasks(Task updateThisTask) {
		if (this.isEditingTitle == true) {
			updateThisTask.title = this.newTaskDetails.title;
		}
		if (this.isEditingPlace == true) {
			updateThisTask.place = this.newTaskDetails.place;
		}
		if (this.isEditingStartTime == true) {
			updateThisTask.startTime = this.newTaskDetails.startTime;
		}
		if (this.isEditingEndTime == true) {
			updateThisTask.endTime = this.newTaskDetails.endTime;
		}
		if (this.isEditingProject == true) {
			updateThisTask.project = this.newTaskDetails.project;
		}
		if (this.isEditingDescription == true) {
			updateThisTask.description = this.newTaskDetails.description;
		}
		return updateThisTask;
	}
	
	private boolean datesAreReversed() {
		if (editTo.startTime == Task.EMPTY_TIME || editTo.endTime == Task.EMPTY_TIME) {
			return false;
		}
		if (editTo.startTime.after(editTo.endTime)) {
			return true;
		}
		return false;
	}
}
